using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Traceability.API.APPLications.Commands.TraceabilityInfoshow;
using Traceability.API.Dtos;
using Traceability.API.Services;
using Traceability.Domain;
using Traceability.ErrorCode;
using Traceability.Infrastructure;

namespace Traceability.API.APPLications.CommandHanders.TraceabilityInfoshow
{
    /// <summary>
    /// 根据生产批次查询溯源信息的处理程序
    /// </summary>
    public class GetTraceabilityInfoByBatchQueryHandler : IRequestHandler<GetTraceabilityInfoByBatchQuery, APIResult<TraceabilityInfoDto>>
    {
        private readonly IBaseRepository<TraceabilityInfo> _traceabilityRepository;
        private readonly IBaseRepository<Products> _productRepository;
        private readonly TraceabilityRedisHelper _redisHelper;
        private readonly RedisService _redisService;
        private readonly ILogger<GetTraceabilityInfoByBatchQueryHandler> _logger;
        private const string BatchCacheKeyPrefix = "traceability:batch:";

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="traceabilityRepository">溯源信息仓储</param>
        /// <param name="productRepository">商品仓储</param>
        /// <param name="redisHelper">Redis帮助类</param>
        /// <param name="redisService">Redis服务</param>
        /// <param name="logger">日志记录器</param>
        public GetTraceabilityInfoByBatchQueryHandler(
            IBaseRepository<TraceabilityInfo> traceabilityRepository,
            IBaseRepository<Products> productRepository,
            TraceabilityRedisHelper redisHelper,
            RedisService redisService,
            ILogger<GetTraceabilityInfoByBatchQueryHandler> logger = null)
        {
            _traceabilityRepository = traceabilityRepository;
            _productRepository = productRepository;
            _redisHelper = redisHelper;
            _redisService = redisService;
            _logger = logger;
        }

        /// <summary>
        /// 处理查询请求
        /// </summary>
        /// <param name="request">查询请求</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>查询结果</returns>
        public async Task<APIResult<TraceabilityInfoDto>> Handle(GetTraceabilityInfoByBatchQuery request, CancellationToken cancellationToken)
        {
            _logger?.LogInformation("开始根据生产批次查询溯源信息: {ProductionBatch}", request.ProductionBatch);
            
            var result = new APIResult<TraceabilityInfoDto>();
            
            try
            {
                if (string.IsNullOrWhiteSpace(request.ProductionBatch))
                {
                    result.Code = APIEnum.操作失败;
                    result.Message = "生产批次不能为空";
                    return result;
                }

                // 尝试从Redis缓存获取数据
                string cacheKey = $"{BatchCacheKeyPrefix}{request.ProductionBatch}";
                var cachedDto = await _redisService.GetAsync<TraceabilityInfoDto>(cacheKey);
                
                if (cachedDto != null)
                {
                    _logger?.LogInformation("从缓存获取到溯源信息: {ProductionBatch}", request.ProductionBatch);
                    result.Data = cachedDto;
                    result.Code = APIEnum.查询成功;
                    return result;
                }

                // 从数据库查询
                var query = from t in _traceabilityRepository.GetAll()
                           join p in _productRepository.GetAll() on t.ProductId equals p.ProductId
                           where t.ProductionBatch == request.ProductionBatch
                           select new TraceabilityInfoDto
                           {
                               TraceabilityId = t.TraceabilityId,
                               ProductId = t.ProductId,
                               ProductName = p.ProductName,
                               ProductionBatch = t.ProductionBatch,
                               ShelfLife = t.ShelfLife,
                               ProductionLicenseNumber = t.ProductionLicenseNumber,
                               ManufacturerName = t.ManufacturerName,
                               InformationCompleteness = t.InformationCompleteness,
                               PhotoUrl = t.PhotoUrl,
                               CreatedBy = t.CreatedBy,
                               CreatedTime = t.CreatedTime,
                               ModifiedBy = t.ModifiedBy,
                               ModifiedTime = t.ModifiedTime,
                               IsDeleted = t.IsDeleted
                           };

                var traceabilityInfo = await query.FirstOrDefaultAsync(cancellationToken);

                if (traceabilityInfo == null)
                {
                    _logger?.LogInformation("未找到生产批次为 {ProductionBatch} 的溯源信息", request.ProductionBatch);
                    result.Code = APIEnum.查询失败;
                    result.Message = $"未找到生产批次为 {request.ProductionBatch} 的溯源信息";
                    return result;
                }

                // 缓存结果
                await _redisService.SetAsync(cacheKey, traceabilityInfo, 3600);
                _logger?.LogInformation("已缓存生产批次为 {ProductionBatch} 的溯源信息", request.ProductionBatch);

                result.Data = traceabilityInfo;
                result.Code = APIEnum.查询成功;
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "根据生产批次查询溯源信息时发生错误: {ProductionBatch}, 错误: {ErrorMessage}", 
                    request.ProductionBatch, ex.Message);
                result.Code = APIEnum.查询失败;
                result.Message = $"查询失败: {ex.Message}";
            }

            return result;
        }
    }
} 